using CfgTable;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 控制实体的ui信息显示相关组件
    /// </summary>
    public class EntityUIViewComponent : TReusableEvtComponent
    {
        private UILightDialog dialogWindow;

        protected UINLightDialogItem _lighDialogItem;

        private UIAlertItem _uiAlertItem;
        private Transform _alertTargetTrans;
        private float _alertValue;

        public TViewEntity entity => _entity;

        public override void OnComponentEvent<T>(TComponentEvent eventType, T arg)
        {
            switch (eventType)
            {
                case TComponentEvent.OnEntityObjectStartHide:
                    if (_alertValue > 0)
                    {
                        SetAlertValue(0).Forget();
                    }
                    break;
                default:
                    break;
            }

        }
        public async UniTask<bool> ShowHeadDialogByBubble(int bubble)
        {
            var bubbleCfg = TableCenter.levelEntityBubble.Get(bubble);
            if (bubbleCfg == null)
            {
                LogGame.LogError("EntityBubble config is null,id:" + bubble);
                return false;
            }

            Vector2 uiOffset = Vector2.zero;
            if (bubbleCfg.PositionOffset.Count == 2)
            {
                uiOffset = new Vector2(bubbleCfg.PositionOffset[0], bubbleCfg.PositionOffset[1]);
            }

            await ShowHeadLightDialog(bubbleCfg, uiOffset);
            if (bubbleCfg.JumpId > 0)
            {
                await ShowHeadDialogByBubble(bubbleCfg.JumpId);
            }

            return true;
        }

        public async UniTask ShowHeadLightDialog(CfgLevelEntityBubble cfgBubble, Vector2 uiOffset)
        {
            HideSpeechBubble();
            if (dialogWindow == null)
            {
                dialogWindow = ManagerCenter.UI.GetEntityUI<UILightDialog>();
                if (dialogWindow == null)
                {
                    LogGame.LogError($"{nameof(UILightDialog)}未开启。");
                    return;
                }
            }

            _lighDialogItem = dialogWindow.CreateDialogItem();

            _lighDialogItem.SetFllowTarget(_entity.transform, Vector3.up, uiOffset);

            await _lighDialogItem.StartDialog(cfgBubble, _entity.name);

            dialogWindow = ManagerCenter.UI.GetEntityUI<UILightDialog>();
            dialogWindow?.PutPoolDialogItem(_lighDialogItem);
            _lighDialogItem = null;
        }

        /// <summary>
        /// 显示警戒UI
        /// </summary>
        /// <param name="targetEntity"></param>
        /// <param name="stepAlertValue">阶段性更新的警戒值，包括开始，清零，最大</param>
        /// <param name="uiOffset"></param>
        /// <returns></returns>
        public async UniTask<bool> ShowHeadAlertView(LevelCharacterEntity targetEntity, int stepAlertValue,
            Vector2 uiOffset)
        {
            _alertValue = stepAlertValue;
            if (_uiAlertItem == null)
            {
                if (dialogWindow == null)
                {
                    dialogWindow = ManagerCenter.UI.GetEntityUI<UILightDialog>();
                    if (dialogWindow == null)
                    {
                        return false;
                    }
                }

                _uiAlertItem = dialogWindow.CreateAlertItem();
            }

            var bindPointCom = _entity.GetComponent<EntityBindPointComponent>(ETComponentType.EntityBindPoint);
            var entityHeadTrans = bindPointCom.GetBindPoint(EntityBindPointCommonType.Top);
            _uiAlertItem.SetFllowTarget(entityHeadTrans, Vector3.up, uiOffset);
            if (stepAlertValue > 0 && stepAlertValue < 100) //警戒结束
            {
                _alertTargetTrans = targetEntity.transform;
            }
            else //警戒结束
            {
                _alertTargetTrans = null;
            }

            return await SetAlertValue(stepAlertValue);
        }

        private async UniTask<bool> SetAlertValue(int stepAlertValue)
        {
            _uiAlertItem.SetAlert(stepAlertValue);
            if (stepAlertValue != 0 && stepAlertValue != 100)
            {
                if (_uiAlertItem.isHiding)
                {
                    _uiAlertItem.CancelHide();
                }

                return true;
            }
            else
            {
                await _uiAlertItem.TweenHide();
                dialogWindow.PutPoolAlertItem(_uiAlertItem);
                _uiAlertItem = null;
                _alertValue = 0;
                return false;
            }
        }

        public override void OnUpdate(float deltaTime)
        {
            //客户端自己计算更新怪物警戒值显示，这里不处理警戒结束，警戒结束由服务器通知为准
            if (_alertTargetTrans != null && _uiAlertItem != null && _uiAlertItem.gameObject.activeSelf)
            {
                int viewRange = _entity.viewRange;
                float sqrDistance = (GameMathUtil.UnityPos2LogicPos(_alertTargetTrans.position)
                                     - GameMathUtil.UnityPos2LogicPos(_entity.transform.position)).sqrMagnitude;
                //如果没有英雄靠近，则警戒值逐渐减少
                if (sqrDistance >= viewRange * viewRange)
                {
                    _alertValue -= ShareLevelConst.AlertReduceDelta * deltaTime;
                    _alertValue = _alertValue < 0 ? 0 : _alertValue;
                }
                //否则根据英雄的距离按比例增长
                else
                {
                    int minDetaPerSec = ShareLevelConst.AlertAddMinDelta;
                    int maxDeltaPerSec = ShareLevelConst.AlertAddMaxDelta;
                    float distance = (float)Math.Sqrt(sqrDistance);
                    float minDelta = minDetaPerSec * deltaTime;
                    float maxDelta = maxDeltaPerSec * deltaTime;
                    _alertValue += ShareLevelMathUtil.PlummetCurve(distance, viewRange, minDelta, maxDelta);
                    _alertValue = _alertValue > 99 ? 99 : _alertValue; //本来最大是100%，视图层只到99即可，100%随逻辑层通知刷新
                }

                _uiAlertItem.SetAlert((int)_alertValue);
                _uiAlertItem.RefreshPosition();
            }
        }

        /// <summary>
        /// 隐藏和关闭所有持续性表现的显示
        /// </summary>
        public void HideAllAwaitView()
        {
            if (dialogWindow == null)
            {
                return;
            }
            HideSpeechBubble();
            HideAlertItem();

            dialogWindow = null;
        }

        private void HideSpeechBubble()
        {
            if (_lighDialogItem != null)
            {
                dialogWindow.PutPoolDialogItem(_lighDialogItem);
                _lighDialogItem = null;
            }
        }

        private void HideAlertItem()
        {
            if (_uiAlertItem != null)
            {
                dialogWindow.PutPoolAlertItem(_uiAlertItem);
                _uiAlertItem = null;
                _alertTargetTrans = null;
                _alertValue = 0;
            }
        }

        #region ObjectPool

        public override uint MaxStore => 50;

        public override void OnPoolReset()
        {
            HideAllAwaitView();
        }

        #endregion
    }
}